package com.dm.cloud.service.impl;

import com.alibaba.nacos.common.utils.CollectionUtils;
import com.alibaba.nacos.common.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dm.cloud.api.dto.*;
import com.dm.cloud.api.service.IRolesService;
import com.dm.cloud.api.vo.RolesVo;
import com.dm.cloud.common.R;
import com.dm.cloud.dao.ResourcesDao;
import com.dm.cloud.dao.RoleResourceDao;
import com.dm.cloud.dao.RolesDao;
import com.dm.cloud.dao.UserRoleDao;
import com.dm.cloud.utils.DtoPreOpratrionUtils;
import com.dm.cloud.utils.MysqlLogger;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class RolesServiceImpl implements IRolesService {

    @Autowired
    private RolesDao rolesDao;

    @Autowired
    private UserRoleDao userRoleDao;

    @Autowired
    private RoleResourceDao roleResourceDao;

    @Autowired
    private ResourcesDao resourcesDao;


    @Override
    @Transactional
    public R createRole(RolesVo rolesVo) {

        //判断是否为空
        if(Strings.isBlank(rolesVo.getRoleCode())){
            return R.failure("角色编码不能为空！");
        }
        if(Strings.isBlank(rolesVo.getRoleName())){
            return R.failure("角色名称不能为空！");
        }

        //判断角编码是否存在 角色唯一
        QueryWrapper<Roles> query = new QueryWrapper<>();
        query.eq("role_code",rolesVo.getRoleCode());
        query.eq("delete_flag",0);

        if(rolesDao.selectCount(query)>0){
            return R.failure("该角色编码已存在！");
        }

        //判断角色名称是否存在 角色唯一
        query = new QueryWrapper<>();
        query.eq("role_name",rolesVo.getRoleName());
        query.eq("delete_flag",0);

        if(rolesDao.selectCount(query)>0){
            return R.failure("该角色名称已存在！");
        }

        try{
            //添加角色信息
            Roles roles =new Roles();
            BeanUtils.copyProperties(rolesVo,roles);

            new DtoPreOpratrionUtils<Roles>().preInsert(roles);
            rolesDao.insert(roles);

            //获取插入的角色的ID
            QueryWrapper idQuery = new QueryWrapper();
            idQuery.eq("role_code",rolesVo.getRoleCode());
            idQuery.eq("role_name",rolesVo.getRoleName());
            idQuery.eq("delete_flag",0);
            idQuery.last(" limit 1 ");
            Roles recourd = rolesDao.selectOne(idQuery);

            Integer roleId = recourd.getId();
            //添加资源信息
            if(CollectionUtils.isNotEmpty(rolesVo.getMenu())){
                List<RoleResource> insertList = new ArrayList<>();
                for (Integer menu : rolesVo.getMenu()) {
                    RoleResource insert1 = new RoleResource();
                    insert1.setRoleId(roleId);
                    insert1.setResourceId(menu);
                    insertList.add(insert1);
                }
                roleResourceDao.batchInsert(insertList);
            }
            MysqlLogger.info(String.format("添加角色【%s】！", rolesVo.getRoleName()));
            return R.success("角色添加成功");
        }catch (Exception ex){
            log.error(String.format("添加角色【%s】失败！", rolesVo.getRoleName()));
            return R.failure("角色添加失败！");
        }
    }

    @Override
    public R updateRole(RolesVo rolesVo) {

        //判断是否为空
        if(Strings.isBlank(rolesVo.getRoleCode())){
            return R.failure("角色编码不能为空！");
        }
        if(Strings.isBlank(rolesVo.getRoleName())){
            return R.failure("角色名称不能为空！");
        }

        //判断角编码是否存在 角色唯一
        QueryWrapper<Roles> query = new QueryWrapper<>();
        query.eq("role_code",rolesVo.getRoleCode());
        query.eq("delete_flag",0);
        query.ne("id",rolesVo.getId());

        if(rolesDao.selectCount(query)>0){
            return R.failure("该角色编码已存在！");
        }

        //判断角色名称是否存在 角色唯一
        query = new QueryWrapper<>();
        query.eq("role_name",rolesVo.getRoleName());
        query.eq("delete_flag",0);
        query.ne("id",rolesVo.getId());

        if(rolesDao.selectCount(query)>0){
            return R.failure("该角色名称已存在！");
        }

        try {
            //修改角色信息
            Roles roles =new Roles();
            BeanUtils.copyProperties(rolesVo,roles);
            new DtoPreOpratrionUtils<Roles>().preUpdate(roles);
            rolesDao.updateById(roles);

            //添加资源信息
            if(CollectionUtils.isNotEmpty(rolesVo.getMenu())){
                //删除原有资源列表
                QueryWrapper deleteSearcher = new QueryWrapper();
                deleteSearcher.eq("role_id",rolesVo.getId());
                roleResourceDao.delete(deleteSearcher);

                List<RoleResource> insertList = new ArrayList<>();
                for (Integer menu : rolesVo.getMenu()) {
                    RoleResource insert1 = new RoleResource();
                    insert1.setRoleId(rolesVo.getId());
                    insert1.setResourceId(menu);
                    insertList.add(insert1);
                }
                roleResourceDao.batchInsert(insertList);
            }
            MysqlLogger.info(String.format("修改角色【%s】信息！",rolesVo.getRoleName()));
            return R.success("角色信息修改成功");
        }catch (Exception ex){
            log.error(String.format("修改角色【%s】信息失败！",rolesVo.getRoleName()));
            return R.failure("角色信息修改失败！");
        }

    }

    /**
     * 逻辑删除 不删除相应资源
     * @param rolesVo
     * @return
     */
    @Override
    public R deleteRole(RolesVo rolesVo) {
        if(null == rolesVo.getId()){
            return R.failure("角色ID不能为空！");
        }
        try {
            Roles roles = new Roles();
            roles.setId(rolesVo.getId());
            roles.setDeleteFlag(1);
            new DtoPreOpratrionUtils<Roles>().preUpdate(roles);
            rolesDao.updateById(roles);
            MysqlLogger.info(String.format("删除角色【%s】！",rolesVo.getRoleName()));
            return R.success("角色信息删除成功");
        }catch (Exception ex){
            log.error(String.format("角色【%s】信息删除失败！",rolesVo.getRoleName()));
            return R.failure("角色信息删除失败！");
        }
    }

    @Override
    public R selectPage(RolesVo rolesVo) {
        List<RolesVo> result = new ArrayList<>();

        QueryWrapper<Roles> usersQueryWrapper = new QueryWrapper<>();
        if(StringUtils.isNotBlank(rolesVo.getRoleCode())){
            usersQueryWrapper.like("role_code",rolesVo.getRoleCode());
        }
        if(StringUtils.isNotBlank(rolesVo.getRoleName())){
            usersQueryWrapper.like("role_name",rolesVo.getRoleName());
        }
        if(null != rolesVo.getStatus()){
            usersQueryWrapper.like("status",rolesVo.getStatus());
        }
        usersQueryWrapper.eq("delete_flag",0);
        usersQueryWrapper.orderByDesc("update_date");
        List<Roles> list = rolesDao.selectList(usersQueryWrapper);

        for (Roles role : list) {
            RolesVo rin = new RolesVo();
            BeanUtils.copyProperties(role,rin);

            result.add(rin);
        }
        return R.success(result);
    }

    @Override
    public R getRoleById(String roleId) {

        RolesVo result =new RolesVo();

        Roles record = rolesDao.selectById(roleId);

        BeanUtils.copyProperties(record,result);

        //只找最里面的一层资源 会自动把最外层的资源带上
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("role_id",roleId);
        List<RoleResource> records = roleResourceDao.selectList(queryWrapper);

        List<Integer> resourceIdList =  records.stream().map(e->e.getResourceId()).collect(Collectors.toList());

        if(CollectionUtils.isNotEmpty(resourceIdList)) {
            //查询当前ID列表中不存在子节点的
            QueryWrapper<Resources> resourcesQueryWrapper = new QueryWrapper<Resources>();
            resourcesQueryWrapper.in("id", resourceIdList);
            resourcesQueryWrapper.and(wapper -> wapper.notInSql("id", " select parent_id from t_s_resources where delete_flag = 0 and status = 1 and parent_id is not null "));

            List<Resources> resList = resourcesDao.selectList(resourcesQueryWrapper);

            resourceIdList = resList.stream().map(e -> e.getId()).collect(Collectors.toList());
            result.setMenu(resourceIdList);
        }
        return R.success(result);
    }
}
